package export;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Sets;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class MyLangCollector implements Collector<String, Map<String, List<String>>, Map<String, List<String>>> {
    // 需要定义的两个内容
    // 1.类名
    private static final String CLASS_NAME = "LangChange";
    // 2.方法
    private static final String METHOD_NAME = "change";
    // 其他内容
    private static final String KEY_IMPORT = "import";
    private static final String KEY_END = ";";
    private static final Pattern NUM_REG = Pattern.compile("(\\S+)=");
    /**
     * 获取正则表达式
     *
     * @param javaName
     * @return
     */
    private static Pattern getReg(String javaName) {
        String regStr = CLASS_NAME +
            "\\s*\\.\\s*" +
            METHOD_NAME +
            "\\s*\\(\\s*\\\"([^\"]+)\\\"\\s*,\\s*\\\"" +
            javaName +
            "_([^\"]+)\\\"";
        return Pattern.compile(regStr);
    }
    @Override
    public Supplier<Map<String, List<String>>> supplier() {
        return () -> Maps.newHashMap();
    }
    @Override
    public BinaryOperator<Map<String, List<String>>> combiner() {
        return (map1, map2) -> {
            map1.putAll(map2);
            return map1;
        };
    }
    @Override
    public Function<Map<String, List<String>>, Map<String, List<String>>> finisher() {
        return Function.identity();
    }
    @Override
    public Set<Characteristics> characteristics() {
        return Sets.newHashSet();
    }
    /**
     * 主要方法
     *
     * @return 消化
     */
    @Override
    public BiConsumer<Map<String, List<String>>, String> accumulator() {
        return (map, path) -> {
            // 获取Java 名称
            String javaName = getName(path);
            Pattern reg = getReg(javaName);
            // 读取文件内容
            StringBuilder tempSB = new StringBuilder();
            // 非并行处理
            List<String> list = (List<String>) readPath(path)
                // 合并成 一行
                .map(item -> {
                    if (tempSB.length() > 0) {
                        return addReturn(tempSB, item);
                    }
                    return normalReturn(tempSB, item);
                })
                .filter(StringUtils::isNotBlank)
                // 正则匹配
                .flatMap(item -> {
                    Matcher matcher = reg.matcher(item);
                    List<String> lists = new LinkedList<>();
                    while (matcher.find()) {
                        String val = matcher.group(1);
                        String number = matcher.group(2);
                        lists.add(number + "=" + val);
                    }
                    return lists.stream();
                })
                // 排序
                .sorted(Comparator.comparing(item -> {
                    Matcher matcher = NUM_REG.matcher(item);
                    matcher.find();
                    String number = matcher.group(1);
                    return Integer.parseInt(number);
                }))
                .parallel()
                .sequential()
                // 添加 java
                .map(item -> javaName + "_" + item)
                .collect(Collectors.toList());
            if (list.isEmpty()) {
                return;
            }
            map.put(javaName, list);
        };
    }
    /**
     * 可以直接返回就直接 返回并清空 tempSB
     * 不就null 继续拼接
     *
     * @param tempSB
     * @param item
     * @return
     */
    private String addReturn(StringBuilder tempSB, String item) {
        tempSB.append(item.trim());
        int classIndex = item.lastIndexOf(CLASS_NAME);
        int endIndex = item.lastIndexOf(KEY_END);
        if (endIndex > classIndex) {
            String res = tempSB.toString();
            tempSB.setLength(0);
            return res;
        }
        return null;
    }
    /**
     * 判断需要返回的内容, 不能直接返回就添加到 tempSB
     *
     * @param tempSB 累加内容
     * @param item   原生
     * @return
     */
    private String normalReturn(StringBuilder tempSB, String item) {
        // 去掉 import 开头的内容
        if (item.startsWith(KEY_IMPORT)) {
            return null;
        }
        //
        int classIndex = item.lastIndexOf(CLASS_NAME);
        if (classIndex == -1) {
            return null;
        }
        int endIndex = item.lastIndexOf(KEY_END);
        if (endIndex > classIndex) {
            return item.trim();
        }
        // 这里需要 合并
        tempSB.append(item.trim());
        return null;
    }
    /**
     * 读取文件
     *
     * @param path
     * @return
     */
    private Stream<String> readPath(String path) {
        try {
            return Files.lines(Paths.get(path));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 获取 java 类名
     *
     * @param path
     * @return
     */
    private String getName(String path) {
        int end = path.lastIndexOf(".");
        int start = path.lastIndexOf("/");
        if (start == -1) {
            start = path.lastIndexOf("\\");
        }
        return path.substring(start + 1, end);
    }
}